package com.panfeng.xcloud.boss.provider.assets.aspect;

import com.panfeng.xcloud.common.core.page.PageResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class CachePagingAspect {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    Logger logger = LoggerFactory.getLogger(CachePagingAspect.class);

    @Around("within(@org.springframework.stereotype.Service *) && @annotation(cachePaging)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint, CachePaging cachePaging) throws Throwable {
        String keyPrefix = cachePaging.keyPrefix();
        Object[] objects = proceedingJoinPoint.getArgs();
        Object param = objects[0];

//        Field field = param.getClass().getDeclaredField("pageNumber");
//        field.setAccessible(true);//暴力访问私有属性
//        Integer pageNumber = (Integer)field.get(param);

        String key = keyPrefix + ":hashCode_" + JSONObject.fromObject(param).hashCode();

        Object redisObject = redisTemplate.opsForValue().get(key);
        if (redisObject == null) {
            Object mysqlObject = proceedingJoinPoint.proceed();
            JSONObject mysqlJsonObject = JSONObject.fromObject(mysqlObject);
            Object listObj = mysqlJsonObject.get("items");
            JSONArray listJsonArray = JSONArray.fromObject(listObj);
            if (listJsonArray != null && listJsonArray.size() > 0) {
                redisTemplate.opsForValue().set(key, mysqlJsonObject.toString(), cachePaging.expire(), TimeUnit.SECONDS);
            }
            return mysqlObject;
        } else {
            JSONObject redisJsonObject = JSONObject.fromObject(redisObject);
            Object listObj = redisJsonObject.get("items");
            List list = (List) JSONArray.toCollection(JSONArray.fromObject(listObj), cachePaging.clazz());
            Integer pageNumber = (Integer) redisJsonObject.get("pageNumber");
            Integer pageSize = (Integer) redisJsonObject.get("pageSize");
            Integer totalPage = (Integer) redisJsonObject.get("totalPage");
            Integer totalCount = (Integer) redisJsonObject.get("totalCount");

            PageResponse redis = new PageResponse();
            redis.setPageNumber(pageNumber);
            redis.setPageSize(pageSize);
            redis.setTotalPage(totalPage);
            redis.setTotalCount(totalCount);
            redis.setItems(list);
            return redis;
        }
    }

}
